<template>
  <div
    class="hash-calendar"
    :class="calcHashCalendarClass"
    v-show="isShowDatetimePicker"
    :style="calcHashCalendarStyle"
    @click="close"
  >
    <div class="calendar_content" @click.stop>
      <div class="calendar_title" ref="calendarTitle">
        <div class="calendar_title_date">
          <span
            v-if="pickerType !== 'time'"
            class="calendar_title_date_year"
            :class="{'calendar_title_date_active': isShowCalendar}"
            @click="showCalendar"
          >{{ checkedDate.year + '年'+ (checkedDate.month + 1)+ '月'+ checkedDate.day + '日'}}</span>
          <!-- <span
            v-if="pickerType !== 'date'"
            class="calendar_title_date_time"
            :class="{'calendar_title_date_active': !isShowCalendar}"
            @click="showTime"
          >{{ }}</span> -->
        </div>
        <div
          v-if="showTodayButton"
          class="calendar_confirm"
          @click="today"
        >今天</div>
        <div class="calendar_confirm" v-if="model === 'dialog'" @click="confirm">确定</div>
      </div>
      <calendar
        ref="calendar"
        v-if="pickerType !== 'time'"
        :show="isShowCalendar"
        v-bind="{...$props, ...$attrs}"
        @height="heightChange"
        @touchstart="touchStart"
        @touchmove="touchMove"
        @touchend="touchEnd"
        @slidechange="slideChange"
        @change="dateChange"
        @clickDate="clickDateHandler"
      ></calendar>
    </div>
  </div>
</template>

<script>
import Calendar from "./Calendar.vue";
import { formatDate } from "../utils/util";

export default {
  props: {
    visible: {
      // 是否显示日历组件
      type: Boolean,
      default: false
    },
    pickerType: {
      // 选择器类型 datetime：日期+时间   date：日期   time：时间
      type: String,
      default: "datetime"
    },
    showTodayButton: {
      // 是否显示返回今日按钮
      type: Boolean,
      default: true
    },
    defaultDatetime: {
      // 默认时间
      type: Date,
      default() {
        return new Date();
      }
    },
    format: null, // 确认选择之后，返回的日期格式
    model: {
      type: String,
      default: "inline"
    },
    // 日期下面的标记
    markDate: {
      type: Array,
      default: () => []
    },
  },
  components: {
    Calendar
  },
  name: "VueHashCalendar",
  data() {
    return {
      checkedDate: {
        year: new Date().getFullYear(),
        month: new Date().getMonth(),
        day: new Date().getDate(),
        hours: new Date().getHours(),
        minutes: new Date().getMinutes()
      }, // 被选中的日期
      isShowCalendar: false, // 是否显示日历选择控件
      calendarContentHeight: 0, // 日历组件高度
      calendarTitleHeight: 0, // 日历组件标题高度
      firstTimes: true, // 第一次触发
      triggerTodayMethod: 0 // 用于触发calendar组件的today方法
    };
  },
  mounted() {
    if (this.model === "inline") {
      this.isShowDatetimePicker = true;
    }
  },
  watch: {
    defaultDatetime(val) {
      if (!(val instanceof Date)) {
        throw new Error(
          `The calendar component's defaultDate must be date type!`
        );
      }
    },
    pickerType: {
      handler(val) {
        if (val === "time") {
          this.showTime();
        }
      },
      immediate: true
    },
    checkedDate: {
      handler() {
        let date = new Date(
          `${this.checkedDate.year}/${this.checkedDate.month + 1}/${
            this.checkedDate.day
          } ${this.checkedDate.hours}:${this.checkedDate.minutes}`
        );
        if (this.format) {
          date = formatDate(date, this.format);
        }
        this.$emit("change", date);
      },
      deep: true
    },
    visible: {
      handler(val) {
        this.isShowCalendar = val;
        const that = this;
        this.$nextTick(() => {
          wx
            .createSelectorQuery()
            .select("calendar_title")
            .boundingClientRect()
            .exec(rect => {
              that.calendarTitleHeight = rect.height;
              })
          // this.calendarTitleHeight = this.$refs.calendarTitle.offsetHeight;
        });
      },
      immediate: true
    }
  },
  computed: {
    isShowDatetimePicker: {
      // 是否显示日期控件
      get() {
        return this.visible;
      },
      set(val) {
        this.$emit("update:visible", val);
      }
    },
    calcHashCalendarClass() {
      return this.model === "inline" ? "calendar_inline" : "";
    },
    calcHashCalendarStyle() {
      return `height:${this.model === "inline" ? this.calendarContentHeight : undefined}px`;
    },
    calendarContentStyle() {
      return `height:${this.calendarContentHeight}px`
    },
    calcDateContent() {
     return `${this.fillNumber(this.checkedDate.hours)}:${this.fillNumber(this.checkedDate.minutes)}`
    }
  },
  methods: {
    clickDateHandler(dateString) {
      this.$emit('clickDate', dateString);
    },
    today() {
      this.triggerTodayMethod = 1;
      setTimeout(() => {
        this.triggerTodayMethod = 0;
      }, 100);
      // this.$refs.calendar.today();
    },
    dateChange(date) {
      date.hours = this.checkedDate.hours;
      date.minutes = this.checkedDate.minutes;
      this.checkedDate = date;
    },
    dateClick(date) {
      date.hours = this.checkedDate.hours;
      date.minutes = this.checkedDate.minutes;
      this.checkedDate = date;

      let fDate = new Date(
        `${this.checkedDate.year}/${this.checkedDate.month + 1}/${
          this.checkedDate.day
        } ${this.checkedDate.hours}:${this.checkedDate.minutes}`
      );
      if (this.format) {
        fDate = formatDate(fDate, this.format);
      }
      this.$emit("dateClick", fDate);
    },
    timeChange(date) {
      date.year = this.checkedDate.year;
      date.month = this.checkedDate.month;
      date.day = this.checkedDate.day;
      this.checkedDate = date;
    },
    confirm() {
      // 确认选择时间
      let date = new Date(
        `${this.checkedDate.year}/${this.checkedDate.month + 1}/${
          this.checkedDate.day
        } ${this.checkedDate.hours}:${this.checkedDate.minutes}`
      );
      if (this.format) {
        date = formatDate(date, this.format);
      }
      this.$emit("confirm", date);
      if (this.model === "dialog") {
        this.close();
      }
    },
    show() {
      this.isShowDatetimePicker = true;
    },
    close() {
      this.isShowDatetimePicker = false;
    },
    fillNumber(val) {
      // 小于10，在前面补0
      return val > 9 ? val : "0" + val;
    },
    showCalendar() {
      // 显示日历控件
      this.isShowCalendar = true;
    },
    showTime() {
      // 显示时间选择控件
      this.isShowCalendar = false;
    },
    heightChange(height) {
      // 高度变化
      if (!this.firstTimes && this.model === "dialog") return;

      this.calendarContentHeight = height + this.calendarTitleHeight;
      this.firstTimes = false;
    },
    touchStart(event) {
      // 监听手指开始滑动事件
      this.$emit("touchstart", event);
    },
    touchMove(event) {
      // 监听手指开始滑动事件
      this.$emit("touchmove", event);
    },
    touchEnd(event) {
      // 监听手指开始滑动事件
      this.$emit("touchend", event);
    },
    slideChange(direction) {
      // 滑动方向改变
      this.$emit("slidechange", direction);
    }
  }
};
</script>

<style lang="stylus" scoped>
@import '../style/common.styl';

.hash-calendar {
  position: relative;
  width: 100%;
  height: 222px;
  box-shadow:0px 9px 18px 0px rgba(220,221,224,1);
  border-radius:8px;
  background: white;
  overflow: hidden;
}

.calendar_inline {
  position: relative;
  width: 100%;
  height: auto;
  background: none;
  z-index: 1;
}

.calendar_content {
  width: 100%;
  height: 222px;
  display: flex;
  flex-wrap: wrap;
  overflow: hidden;
}

.calendar_title {
  position: absolute;
  width: 100%;
  left: 0;
  top: 0;
  background: bg-color;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
}

.calendar_title_date {
  color: vice-font-color;
  background: white;
  paddingAround();
}

.calendar_title_date_active {
  color: main-font-color;
  font-weight: semi-bold;
  font-size: 13px;
}

.calendar_title_date_time {
  margin-left: px2vw(20px);
}

.calendar_confirm {
  color: main-color;
  margin-right: px2vw(34px);
}

.today_disable {
  color: disabled-font-color;
}
</style>
